package edu.rit.drh4818.raytracing.shaders.lighting;

import java.awt.Color;

import edu.rit.drh4818.raytracing.light.ColorMixer;
import edu.rit.drh4818.raytracing.light.PointLight;
import edu.rit.drh4818.raytracing.shaders.Shader;
import edu.rit.drh4818.raytracing.util.Intersection;
import edu.rit.drh4818.raytracing.util.Ray;
import edu.rit.drh4818.raytracing.util.Scene;

/**
 * Shader which applies phong shading to an object.
 * 
 * @author Darren Headrick
 *
 */
public class PhongShader implements Shader 
{
	/**
	 * Calculate color using phong shading model.
	 */
	public Color getColor(Intersection in, int depth) 
	{
		Color Sum = new Color(0,0,0);
		Ray view =  Ray.rayFromPoints( in.getX(), in.getY(), in.getZ(), 
				-in.ray.xd, -in.ray.yd, -in.ray.zd );
		
		for( PointLight light : Scene.instance.lights )
		{
			Ray source = light.createShadowRay( in );
			Ray reflected = source.getReflectedRay(in);
			
			if( reflected != null )
			{
				Color totalLight = light.getColor( in );
				
				if( totalLight.getRed() > 0 || totalLight.getBlue() > 0 || totalLight.getGreen() > 0 )
				{
					 // diffuse
					Color diffuse = ColorMixer.multiply(
							ColorMixer.multiply( totalLight, in.obj.prop.diffuse ), in.obj.prop.kd );
					diffuse = ColorMixer.multiply( diffuse, source.dot( in.getNormal() ) );
					Sum = ColorMixer.add( Sum, diffuse );
					
					// specular
					Color specular = ColorMixer.multiply(ColorMixer.multiply( totalLight, in.obj.prop.diffuse ), in.obj.prop.ks );
					specular = ColorMixer.multiply( specular, Math.pow( reflected.dot( view ), in.obj.prop.ke ) );
					Sum = ColorMixer.add( Sum, specular );
				}
			}
		}
		
		if( in.obj.prop.shader != null )
		{
			return ColorMixer.add( Sum, 
					ColorMixer.multiply( in.obj.prop.shader.getColor(in, depth+1), in.obj.prop.ka ) );
		}
		
		return ColorMixer.add( Sum, ColorMixer.multiply(in.obj.prop.ambient, in.obj.prop.ka ) );
	}
}
